
//A.24 getCBvec.c 
    
   /****************************************************************** 
    
       iLBC Speech Coder ANSI-C Source Code 
    
       getCBvec.c  
    
       Copyright (c) 2001, 
       Global IP Sound AB. 
       All rights reserved. 
    
   ******************************************************************/ 
    
#include"constants.h" 
#include"iLBC_define.h" 

   #include <string.h> 
    
   /*----------------------------------------------------------------* 
    *  Construct codebook vector for given index. 
     
   Andersen et. al.  Experimental - Expires March 20th, 2003       117 
    
                     Internet Low Bit Rate Codec       September 2002 
    
    *---------------------------------------------------------------*/ 
    
   void getCBvec( 
       float *cbvec,   /* (o) Constructed codebook vector */ 
       float *mem,     /* (i) Codebook buffer */ 
       int index,      /* (i) Codebook index */ 
       int lMem,       /* (i) Length of codebook buffer */ 
       int cbveclen/* (i) Codebook vector length */ 
   ){ 
       int j, k, n, memInd, sFilt; 
       float tmpbuf[CB_MEML]; 
       int base_size; 
       int ilow, ihigh; 
       float alfa, alfa1; 
    
       /* Determine size of codebook sections */ 
    
       base_size=lMem-cbveclen+1; 
        
       if (cbveclen==SUBL) { 
           base_size+=cbveclen/2; 
       } 
    
       /* No filter -> First codebook section */ 
        
       if (index<lMem-cbveclen+1) { 
    
           /* first non-interpolated vectors */ 
    
           k=index+cbveclen; 
           /* get vector */ 
           memcpy(cbvec, mem+lMem-k, cbveclen*sizeof(float)); 
    
       } else if (index < base_size) { 
    
           k=2*(index-(lMem-cbveclen+1))+cbveclen; 
        
           ihigh=k/2; 
           ilow=ihigh-5; 
    
           /* Copy first noninterpolated part */ 
    
           memcpy(cbvec, mem+lMem-k/2, ilow*sizeof(float)); 
    
           /* interpolation */ 
    
           alfa1=(float)0.2; 
           alfa=0.0; 
           for (j=ilow; j<ihigh; j++) { 
               cbvec[j]=((float)1.0-alfa)*mem[lMem-k/2+j]+ 
                   alfa*mem[lMem-k+j]; 
               alfa+=alfa1; 
           } 
     
    
           /* Copy second noninterpolated part */ 
    
           memcpy(cbvec+ihigh, mem+lMem-k+ihigh,  
               (cbveclen-ihigh)*sizeof(float)); 
    
       } 
    
       /* Higher codebbok section based on filtering */ 
    
       else { 
    
           /* first non-interpolated vectors */ 
    
           if (index-base_size<lMem-cbveclen+1) { 
               float tempbuff2[CB_MEML+CB_FILTERLEN+1]; 
               float *pos; 
               float *pp, *pp1; 
    
               memset(tempbuff2, 0, CB_HALFFILTERLEN*sizeof(float)); 
               memcpy(&tempbuff2[CB_HALFFILTERLEN], mem,  
                   lMem*sizeof(float)); 
               memset(&tempbuff2[lMem+CB_HALFFILTERLEN], 0,  
                   (CB_HALFFILTERLEN+1)*sizeof(float)); 
    
               k=index-base_size+cbveclen; 
               sFilt=lMem-k; 
               memInd=sFilt+1-CB_HALFFILTERLEN; 
    
               /* do filtering */ 
               pos=cbvec; 
               memset(pos, 0, cbveclen*sizeof(float)); 
               for (n=0; n<cbveclen; n++) { 
                   pp=&tempbuff2[memInd+n+CB_HALFFILTERLEN]; 
                   pp1=&cbfiltersTbl[0]; 
                   for (j=0;j<CB_FILTERLEN;j++) { 
                       (*pos)+=(*pp++)*(*pp1++); 
                   } 
                   pos++; 
               } 
           } 
    
           /* interpolated vectors */ 
    
           else { 
               float tempbuff2[CB_MEML+CB_FILTERLEN+1]; 
    
               float *pos; 
               float *pp, *pp1; 
               int i; 
    
               memset(tempbuff2, 0, CB_HALFFILTERLEN*sizeof(float)); 
               memcpy(&tempbuff2[CB_HALFFILTERLEN], mem,  
     
                   lMem*sizeof(float)); 
               memset(&tempbuff2[lMem+CB_HALFFILTERLEN], 0,  
                   (CB_HALFFILTERLEN+1)*sizeof(float)); 
    
               k=2*(index-base_size-(lMem-cbveclen+1))+cbveclen; 
               sFilt=lMem-k; 
               memInd=sFilt+1-CB_HALFFILTERLEN; 
    
               /* do filtering */ 
               pos=&tmpbuf[sFilt]; 
               memset(pos, 0, k*sizeof(float)); 
               for (i=0; i<k; i++) { 
                   pp=&tempbuff2[memInd+i+CB_HALFFILTERLEN]; 
                   pp1=&cbfiltersTbl[0]; 
                   for (j=0;j<CB_FILTERLEN;j++) { 
                       (*pos)+=(*pp++)*(*pp1++); 
                   } 
                   pos++; 
               } 
    
               ihigh=k/2; 
               ilow=ihigh-5; 
    
               /* Copy first noninterpolated part */ 
    
               memcpy(cbvec, tmpbuf+lMem-k/2, ilow*sizeof(float)); 
    
               /* interpolation */ 
    
               alfa1=(float)0.2; 
               alfa=0.0; 
               for (j=ilow; j<ihigh; j++) { 
                   cbvec[j]=((float)1.0-alfa)* 
                       tmpbuf[lMem-k/2+j]+alfa*tmpbuf[lMem-k+j]; 
                   alfa+=alfa1; 
               } 
    
               /* Copy second noninterpolated part */ 
    
               memcpy(cbvec+ihigh, tmpbuf+lMem-k+ihigh,  
                   (cbveclen-ihigh)*sizeof(float)); 
           } 
       } 
   } 
    
    
